package gbase

import (
	"fmt"
	"sort"
	"sync"
)


// ==================== 插件模式 ====================

// IPlugin 插件接口
type IPlugin[T any] interface {
	// Process 处理逻辑
	Process(input T) (T, error)

	// Name 插件名称（用于标识和日志）
	Name() string

	// Priority 优先级（数字越小优先级越高，执行越早）
	Priority() int

	// Enabled 是否启用
	Enabled() bool
}

// PluginManager 插件管理器
type PluginManager[T any] struct {
	plugins []IPlugin[T]
	mu      sync.RWMutex
}

// NewPluginManager 创建插件管理器
func NewPluginManager[T any]() *PluginManager[T] {
	return &PluginManager[T]{
		plugins: make([]IPlugin[T], 0),
	}
}

// Register 注册插件
func (pm *PluginManager[T]) Register(plugin IPlugin[T]) {
	pm.mu.Lock()
	defer pm.mu.Unlock()

	// 检查是否已注册
	for _, p := range pm.plugins {
		if p.Name() == plugin.Name() {
			return // 已存在，不重复注册
		}
	}

	pm.plugins = append(pm.plugins, plugin)
	// 按优先级排序
	pm.sortPlugins()
}

// Unregister 注销插件
func (pm *PluginManager[T]) Unregister(name string) {
	pm.mu.Lock()
	defer pm.mu.Unlock()

	for i, p := range pm.plugins {
		if p.Name() == name {
			pm.plugins = append(pm.plugins[:i], pm.plugins[i+1:]...)
			return
		}
	}
}

// Execute 执行所有启用的插件（链式执行）
// 每个插件的输出作为下一个插件的输入
func (pm *PluginManager[T]) Execute(input T) (T, error) {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	result := input
	var err error

	for _, plugin := range pm.plugins {
		if !plugin.Enabled() {
			continue
		}

		result, err = plugin.Process(result)
		if err != nil {
			return result, fmt.Errorf("plugin %s failed: %w", plugin.Name(), err)
		}
	}

	return result, nil
}

// ExecuteUntilError 执行直到遇到错误（短路模式）
func (pm *PluginManager[T]) ExecuteUntilError(input T) (T, error) {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	result := input

	for _, plugin := range pm.plugins {
		if !plugin.Enabled() {
			continue
		}

		var err error
		result, err = plugin.Process(result)
		if err != nil {
			return result, err
		}
	}

	return result, nil
}

// ExecuteAll 执行所有插件（即使出错也继续）
func (pm *PluginManager[T]) ExecuteAll(input T) (T, []error) {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	result := input
	var errors []error

	for _, plugin := range pm.plugins {
		if !plugin.Enabled() {
			continue
		}

		var err error
		result, err = plugin.Process(result)
		if err != nil {
			errors = append(errors, fmt.Errorf("plugin %s: %w", plugin.Name(), err))
		}
	}

	return result, errors
}

// GetPlugins 获取所有插件（按优先级排序）
func (pm *PluginManager[T]) GetPlugins() []IPlugin[T] {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	result := make([]IPlugin[T], len(pm.plugins))
	copy(result, pm.plugins)
	return result
}

// GetPlugin 根据名称获取插件
func (pm *PluginManager[T]) GetPlugin(name string) IPlugin[T] {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	for _, p := range pm.plugins {
		if p.Name() == name {
			return p
		}
	}
	return nil
}

// Clear 清空所有插件
func (pm *PluginManager[T]) Clear() {
	pm.mu.Lock()
	defer pm.mu.Unlock()

	pm.plugins = pm.plugins[:0]
}

// Count 返回插件数量
func (pm *PluginManager[T]) Count() int {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	return len(pm.plugins)
}

// sortPlugins 按优先级排序插件
func (pm *PluginManager[T]) sortPlugins() {
	sort.Slice(pm.plugins, func(i, j int) bool {
		return pm.plugins[i].Priority() < pm.plugins[j].Priority()
	})
}

// ==================== 基础插件实现 ====================

// BasePlugin 基础插件（可嵌入到具体插件中）
type BasePlugin[T any] struct {
	name     string
	priority int
	enabled  bool
}

// NewBasePlugin 创建基础插件
func NewBasePlugin[T any](name string, priority int) *BasePlugin[T] {
	return &BasePlugin[T]{
		name:     name,
		priority: priority,
		enabled:  true,
	}
}

func (p *BasePlugin[T]) Name() string {
	return p.name
}

func (p *BasePlugin[T]) Priority() int {
	return p.priority
}

func (p *BasePlugin[T]) Enabled() bool {
	return p.enabled
}

// SetEnabled 设置启用状态
func (p *BasePlugin[T]) SetEnabled(enabled bool) {
	p.enabled = enabled
}

// ==================== 插件链 ====================

// PluginChain 插件链（支持条件执行）
type PluginChain[T any] struct {
	manager *PluginManager[T]
}

// NewPluginChain 创建插件链
func NewPluginChain[T any]() *PluginChain[T] {
	return &PluginChain[T]{
		manager: NewPluginManager[T](),
	}
}

// Add 添加插件
func (pc *PluginChain[T]) Add(plugin IPlugin[T]) *PluginChain[T] {
	pc.manager.Register(plugin)
	return pc
}

// Execute 执行插件链
func (pc *PluginChain[T]) Execute(input T) (T, error) {
	return pc.manager.Execute(input)
}

// ExecuteIf 条件执行
func (pc *PluginChain[T]) ExecuteIf(input T, condition func(T) bool) (T, error) {
	if !condition(input) {
		return input, nil
	}
	return pc.Execute(input)
}

// ==================== 插件过滤器 ====================

// PluginFilter 插件过滤器（用于筛选插件）
type PluginFilter[T any] func(IPlugin[T]) bool

// FilterByName 按名称过滤
func FilterByName[T any](name string) PluginFilter[T] {
	return func(p IPlugin[T]) bool {
		return p.Name() == name
	}
}

// FilterByPriority 按优先级范围过滤
func FilterByPriority[T any](min, max int) PluginFilter[T] {
	return func(p IPlugin[T]) bool {
		priority := p.Priority()
		return priority >= min && priority <= max
	}
}

// FilterEnabled 过滤启用的插件
func FilterEnabled[T any]() PluginFilter[T] {
	return func(p IPlugin[T]) bool {
		return p.Enabled()
	}
}

// ExecuteWithFilter 使用过滤器执行插件
func (pm *PluginManager[T]) ExecuteWithFilter(input T, filter PluginFilter[T]) (T, error) {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	result := input
	var err error

	for _, plugin := range pm.plugins {
		if !filter(plugin) {
			continue
		}

		result, err = plugin.Process(result)
		if err != nil {
			return result, fmt.Errorf("plugin %s failed: %w", plugin.Name(), err)
		}
	}

	return result, nil
}
